package jmu.edu.yjc.job.method;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jmu.edu.yjc.Utils.EmailUtil;
import jmu.edu.yjc.Utils.RedisCache;
import jmu.edu.yjc.constants.SystemConstants;
import jmu.edu.yjc.domain.entity.Healthy;
import jmu.edu.yjc.domain.entity.MailInfo;
import jmu.edu.yjc.domain.entity.PageView;
import jmu.edu.yjc.domain.vo.healthy.HealthyMessageVo;
import jmu.edu.yjc.domain.vo.healthy.HealthyVo;
import jmu.edu.yjc.server.WebSocketServer;
import jmu.edu.yjc.service.HealthyService;
import jmu.edu.yjc.service.MailInfoService;
import jmu.edu.yjc.service.PageViewService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.websocket.Session;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author yjc
 * @date 2023/4/3 23:56
 */

@Slf4j
@Service("taskService")
public class TaskService {
    @Autowired
    private EmailUtil emailUtil;
    @Resource
    private HealthyService healthyService;
    @Resource
    private MailInfoService mailInfoService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private PageViewService pageViewService;
    @Resource
    private RedisCache redisCache;
    @Transactional
    public void sendMailToUser() throws MessagingException {
        List<HealthyMessageVo> healthyVos = healthyService.queryByAnPushStatus();
        List<MailInfo> mailInfos = new ArrayList<>();
        List<Healthy> healthies = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (HealthyMessageVo vo : healthyVos) {
            String mailMessage = "<strong>尊敬的" + vo.getName() + (SystemConstants.WOMAN.equals(vo.getElderly().getSex())?"女士" : "先生")
                    + "的家属您好: </strong>" + "\n" + "<strong>您的家属：</strong>" +vo.getName() + "于" + sdf.format(vo.getMeasurementTime()) + "所做检查结果如下:" + "\n"
                    + (vo.getBloodPressure() == null ? "" : "<div class= 'p-div'>" + handlingBloodPressure(vo.getBloodPressure()) +"</div>")
                    + (vo.getBloodSugar() == null ? "" : "<div class= 'p-div'>" + handlingBloodSugar(vo.getBloodSugar()) +"</div>")
                    + (vo.getBloodFatCholesterol() == null || vo.getBloodFatTriglyceride() == null ? "" : "<div class= 'p-div'>" + handingBloodFat(vo.getBloodFatCholesterol(),vo.getBloodFatTriglyceride()) +"</div>")
                    + (vo.getHeartRate() == null ? "" : "<div class= 'p-div'>" + handingHeartRate(vo.getHeartRate()) +"</div>")
                    + (vo.getUricAcid() == null ? "" : "<div class= 'p-div'>" + handingUricAcid(vo.getUricAcid(),vo.getElderly().getSex()) +"</div>")
                    + (vo.getVitalCapacity() == null ? "" : "<div class= 'p-div'>" + handingVitalCapacity(vo.getVitalCapacity(),vo.getElderly().getSex()) +"</div>");
            MailInfo mailInfo = MailInfo.builder().content(mailMessage).createTime(new Date())
                    .receiverUserId(vo.getElderly().getUserId()).hid(vo.getId()).build();
            mailInfos.add(mailInfo);
            Healthy healthy = Healthy.builder().id(vo.getId()).pushStatus(SystemConstants.PUSH_STATUS_PUSH).build();
            healthies.add(healthy);
            Map<String, String> map = new HashMap<>();
            map.put("type","mail");
            map.put("hid",vo.getId().toString());
            map.put("content",mailMessage);
            map.put("readStatus","0");
            map.put("receiverUserId",vo.getElderly().getUserId().toString());
            map.put("createTime",sdf.format(new Date()));
            stringRedisTemplate.convertAndSend(SystemConstants.REDIS_CHANNEL_MAIL,JSONObject.toJSONString(map));
            String title = "老年人社区管理与服务平台";
            mailMessage =  "<html>\n" + "<body>\n" + mailMessage + "</body>\n" + "</html>";
            emailUtil.sendHtmlMessage(vo.getElderly().getUser().getEmail(),title, mailMessage);
        }
        healthyService.updateBatchById(healthies);
        mailInfoService.saveBatch(mailInfos);
    }
    public String handlingBloodPressure (Double bloodPressure) {
        String result = "<strong>血压：" + bloodPressure + "mmHg 状态：</strong>";
        if(bloodPressure >= 80 && bloodPressure <= 120) {
            result += "<p class='p-green'>正常</p>\n";
        }else if(bloodPressure < 80) {
            result += "<p class='p-yellow'>过低，正常血压值：120/80毫米汞柱</p> \n";
        }else if(bloodPressure > 120) {
            result += "<p class='p-yellow'>过高，正常血压值：120/80毫米汞柱</p> \n";
        }
        if(bloodPressure < 80 || bloodPressure > 120) {
            result += "<strong>管理好血压要做到： </strong>\n" + "1、 不要吃得过咸，减少钠盐摄入，每人每日食盐摄入量逐步降至<6g，增加钾摄入。\n" +
                    "2、 多锻炼身体，体重控制在健康的范围。\n" + "3、 不吸烟，彻底戒烟，避免被动吸烟；不饮或限制饮酒。\n" +
                    "4、 心情舒畅，减轻精神压力，保持心理平衡和良好睡眠。\n" + "5、血压一旦不稳定，要看医生， 必要时吃降压药。\n";
        }
        return result;
    }
    public String handlingBloodSugar (Double bloodSugar) {
        String result = "<strong>血糖：" + bloodSugar + "mg/dl 状态：</strong>";
        if (bloodSugar >= 3.9 && bloodSugar <= 6.1) {
            result += "<p class='p-green'>正常</p>\n";
        } else if (bloodSugar > 6.1 && bloodSugar <=7 ) {
            result += "<p class='p-yellow'>过高，正常血糖值：3.9~6.1毫摩尔/升</p>\n" ;
        } else if(bloodSugar > 7) {
            result += "<p class='p-red'>高血糖(有危险疑似糖尿病)，正常血糖值：3.9~6.1毫摩尔/升</p>\n" ;
        } else if (bloodSugar < 3.9) {
            result += "<p class='p-yellow'>过低，正常血糖值：3.9~6.1毫摩尔/升</>\n" ;
        }
        if(bloodSugar < 3.9 || bloodSugar > 6.1) {
            result += "<strong>要想血糖不升高，以下3点要做到：</strong>\n" + "1、 保持好身材， 及时减肥。\n" +
                    "2、 调整饮食结构，多吃蔬菜和全麦食物。减少糖和碳水化合物的摄入。\n" +
                    "3、 适度运动是法宝。\n";
        }
        return result;
    }
    public String handingBloodFat(Double cholesterol , Double triglyceride) {
        String result = "<strong>血脂(胆固醇)：" + cholesterol + "mmol/L" + "血脂(甘油三酯)：" + triglyceride + "mmol/L " +  "状态：</strong>";
        if( triglyceride <= 1.7 && (cholesterol >= 2.8 && cholesterol <= 5.2) ) {
            result += "<p class='p-green'>正常</p>\n";
        } else if (triglyceride > 1.7) {
            result += "<p class='p-yellow'>过高，正常血脂值：总胆固醇2.8～5.2mmol/L 甘油三酯：1.7mmol/L以内</p>\n";
        } else {
            if(cholesterol < 2.8) {
                result += "<p class='p-yellow'>过低，正常血脂值：总胆固醇2.8～5.2mmol/L 甘油三酯：1.7mmol/L以内</p>\n";
            }else if(cholesterol > 5.2) {
                result += "<p class='p-yellow'>过高，正常血脂值：总胆固醇2.8～5.2mmol/L 甘油三酯：1.7mmol/L以内</p>\n";
            }
        }
        if(triglyceride > 1.7 || cholesterol < 2.8 || cholesterol > 5.2) {
            result += "<strong>要想保持血脂正常，要做到：</strong>\n" + "1、 少吃动物性脂肪，多果蔬和全麦食物、坚果、廋肉、橄榄油。\n" +
                    "2、 控制体重，拒绝肥胖。\n" + "3、每周至少5天， 每天有至少30分钟中高强度的运动，像登山、游泳等。\n" +
                    "4、持续血脂高，降不下来，必要时看医生吃药。\n";
        }
        return result;
    }
    public String handingHeartRate(Double heartRate) {
        String result = "<strong>心率：" + heartRate + "次/分 状态：</strong>";
        if (heartRate >= 60 && heartRate <= 80) {
            result += "<p class='p-green'>正常</p>\n";
        } else if( heartRate < 60) {
            result += "<p class='p-yellow'>过低，正常心率：60-80次/分</p>\n";
        } else if (heartRate > 80) {
            result += "<p class='p-yellow'>过高，正常心率：60-80次/分</p>\n";
        }
        if(heartRate < 60 || heartRate > 80) {
            result += "<strong>说明：</strong>一个健康成人的心率范围是60-100次/分，大多数人都在60-80次/分之间。小朋友的心率要比成人快，3岁以下的小儿常在100次/分以上。高血压患者，超过每分钟80次时就需要进行心率管理。\n";
        }
        return result;
    }
    public String handingUricAcid(Double uricAcid ,String sex) {
        String result = "<strong>尿酸：" + uricAcid + "mmol/L 状态：</strong>";
        boolean isHight = false;
        if(SystemConstants.WOMAN.equals(sex)) {
            if(uricAcid <= 360){
                result += "<p class='p-green'>正常</p>\n";
            } else {
                isHight = true;
                result += "<p class='p-yellow'>过高，正常尿酸：男性＜420mmol/L，女性＜360mmol/L</p>\n";
            }
        }else {
            if(uricAcid <= 420) {
                result += "<p class='p-green'>正常</p>\n";
            } else {
                isHight = true;
                result += "<p class='p-yellow'>过高，正常尿酸：男性＜420mmol/L，女性＜360mmol/L</p>\n";
            }
        }
        if(isHight) {
            result += "<strong>怎样降低尿酸？可以遵循以下方案：</strong>\n" + "1、 多运动，以中低强度运动为宜，比如游泳、步行、跳舞等。\n" +
                    "2、少吃六类食物：高果糖食物、调味料、咖啡浓茶、啤酒、种子类食物、内脏和鱼类。\n" +
                    "3、 每天的盐摄入量建议不超过6克，喝够充足的白开水。\n";
        }
        return result;
    }
    public String handingVitalCapacity(Double vitalCapacity, String sex) {
        String result = "<strong>肺活量：" + vitalCapacity + "ml 状态：</strong>";
        boolean islow = false;
        if(SystemConstants.WOMAN.equals(sex)) {
            if(vitalCapacity >= 2500) {
                result += "<p class='p-green'>正常</p>\n";
            }else if(vitalCapacity < 2500) {
                islow = true;
                result += "<p class='p-yellow'>过低，正常肺活量：男性3500～4000毫升，女性为2500～3500毫升</p>\n";
            }
        }else {
            if(vitalCapacity >= 3500) {
                result += "<p class='p-green'>正常</p>\n";
            }else if(vitalCapacity < 3500) {
                islow = true;
                result += "<p class='p-yellow'>过低，正常肺活量：男性3500～4000毫升，女性为2500～3500毫升</p>\n";
            }
        }
        if( islow ) {
            result += "<strong>说明：</strong>肺活量检测数值低，说明机体摄氧能力和排出废气的能力差，人体内部的氧供应就不充裕，机体的一些工作就不能正常。" +
                    "一旦机体需要大量消耗氧的情况（如长时间学习、工作、剧烈运动时）就会出现氧供应的严重不足， " +
                    "从而导致诸如头痛、头晕、胸闷、精神萎靡、注意力不集中、记忆力下降、失眠等。\n";
        }
        return result;
    }
    public void redisAndMysqlDataSync() throws ParseException {
        //每日用户浏览量
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = new Date();
        String nowDay = sdf.format(now);
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        //获取前一天的日期
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE,day-1);
        String dayBefore = sdf.format(c.getTime());
        Long count = redisCache.getHyperLogLogCount(dayBefore);
        //浏览量落地
        PageView pageView = new PageView();
        LambdaQueryWrapper<PageView> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PageView::getBrowseDate,dayBefore);
        PageView one = pageViewService.getOne(wrapper);
        if(one != null) {
            pageView.setId(one.getId());
        }
        //设置前一天的浏览量过期时间
        redisCache.expire(dayBefore,25, TimeUnit.HOURS);
        pageView.setBrowseDate(sdf.parse(dayBefore));
        pageView.setBrowseCount(count);
        pageViewService.saveOrUpdate(pageView);
        log.info("now: {}, dayBefore:{}, dayBeforeCount: {}" ,nowDay, dayBefore, count );
    }
}
